package com.xiaoming.backend.dao.impl;

import com.xiaoming.backend.dao.ICarTaskDao;
import com.xiaoming.backend.dao.mapper.CarInfoPOMapper;
import com.xiaoming.backend.dao.mapper.CarTaskPOMapper;
import com.xiaoming.backend.dao.mapper.FacilityPOMapper;
import com.xiaoming.backend.dao.mapper.OthserMapper;
import com.xiaoming.backend.entity.db.example.CarInfoPOExample;
import com.xiaoming.backend.entity.db.example.CarTaskPOExample;
import com.xiaoming.backend.entity.db.po.CarInfoPO;
import com.xiaoming.backend.entity.db.po.CarTaskPO;
import com.xiaoming.backend.entity.db.po.FacilityPO;
import com.xiaoming.backend.entity.db.po.TaskInfoPO;
import com.xiaoming.backend.entity.orm.Task;
import com.xiaoming.backend.result.exception.AppErrorException;
import com.xiaoming.backend.result.exception.error.AppError;
import com.xiaoming.backend.util.DateUtil;
import com.xiaoming.backend.util.DeepCopyUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class CarTaskDao implements ICarTaskDao {
    private final CarTaskPOMapper carTaskPOMapper;

    private final CarInfoPOMapper carInfoPOMapper;

    private final FacilityPOMapper facilityPOMapper;

    private final OthserMapper othserMapper;

    @Override
    public int insertCarTask(CarTaskPO carTaskPO) {
        return carTaskPOMapper.insert(carTaskPO);
    }

    @Override
    public List<Task> getTaskInfo(Long driverId, int flag, String status, Long facilityId) {
        List<TaskInfoPO> taskInfos = othserMapper.getTaskInfo(driverId, flag, status, facilityId);
        return taskInfos.stream()
                .map(po -> DeepCopyUtil.copyByJackson(po, Task.class))
                .collect(Collectors.toList());
    }

    @Override
    public CarTaskPO startTask(Long taskId, String status, Long facilityId, Long userId) {
        CarTaskPO carTaskPO = carTaskPOMapper.selectByPrimaryKey(taskId);
        if (carTaskPO == null){
            log.error("taskId: {}",taskId);
            throw new AppErrorException(AppError.FIND_TASK_ERROR);
        }
        FacilityPO facilityPO = facilityPOMapper.selectByPrimaryKey(facilityId);
        carTaskPO.setTaskStatus(status);
        carTaskPO.setRoute(carTaskPO.getRoute() + " -> " + facilityPO.getFacilityName());
        carTaskPO.setStartDate(new Date());

        CarInfoPOExample e = new CarInfoPOExample();
        e.createCriteria().andDriverIdEqualTo(userId);
        List<CarInfoPO> carInfoPOS = carInfoPOMapper.selectByExample(e);
        if (carInfoPOS.isEmpty()){
            throw new AppErrorException(AppError.CAR_NOT_FIND_ERROR);
        }
        carTaskPO.setVehicleId(carInfoPOS.get(0).getCarId());

        carTaskPOMapper.updateByPrimaryKey(carTaskPO);
        return carTaskPO;
    }

    @Override
    public Integer finishTask(Long taskid, String status) {
        CarTaskPO carTaskPO = carTaskPOMapper.selectByPrimaryKey(taskid);
        if (carTaskPO == null){
            throw new AppErrorException(AppError.FIND_TASK_ERROR);
        }
        carTaskPO.setTaskStatus(status);
        carTaskPO.setEndDate(new Date());
        carTaskPOMapper.updateByPrimaryKey(carTaskPO);
        return Math.toIntExact(carTaskPO.getOrderId());
    }

    @Override
    public String getTaskCount(Long userId) {
        CarInfoPOExample carInfoPOExample = new CarInfoPOExample();
        carInfoPOExample.createCriteria().andDriverIdEqualTo(userId);
        List<CarInfoPO> carInfoPOS = carInfoPOMapper.selectByExample(carInfoPOExample);
        if (carInfoPOS.isEmpty()){
            throw new AppErrorException(AppError.CAR_NOT_FIND_ERROR);
        }
        CarTaskPOExample e = new CarTaskPOExample();
        e.createCriteria().andVehicleIdEqualTo(carInfoPOS.get(0).getCarId());
        long l = carTaskPOMapper.countByExample(e);
        return String.valueOf(l);
    }

    @Override
    public String getTaskCount(Long userId, Date date) {
        CarInfoPOExample carInfoPOExample = new CarInfoPOExample();
        carInfoPOExample.createCriteria().andDriverIdEqualTo(userId);
        List<CarInfoPO> carInfoPOS = carInfoPOMapper.selectByExample(carInfoPOExample);
        if (carInfoPOS.isEmpty()){
            throw new AppErrorException(AppError.CAR_NOT_FIND_ERROR);
        }
        CarTaskPOExample e = new CarTaskPOExample();
        e.createCriteria().andVehicleIdEqualTo(carInfoPOS.get(0).getCarId()).andEndDateGreaterThanOrEqualTo(DateUtil.removeTime(date));
        long l = carTaskPOMapper.countByExample(e);
        return String.valueOf(l);
    }

    @Override
    public Long getTaskAdminCount(Long facilityId) {
        CarInfoPOExample carInfoPOExample = new CarInfoPOExample();
        carInfoPOExample.createCriteria().andFacilityIdEqualTo(facilityId);
        List<CarInfoPO> carInfoPOS = carInfoPOMapper.selectByExample(carInfoPOExample);
        if (carInfoPOS.isEmpty()){
            throw new AppErrorException(AppError.CAR_NOT_FIND_ERROR);
        }
        List<Long> carId = carInfoPOS.stream()
                .map(CarInfoPO::getCarId)
                .toList();
        CarTaskPOExample e = new CarTaskPOExample();
        e.createCriteria().andVehicleIdIn(carId);
        return carTaskPOMapper.countByExample(e);
    }

    @Override
    public Long getTaskAdminCount(Long facilityId, Date date) {
        CarInfoPOExample carInfoPOExample = new CarInfoPOExample();
        carInfoPOExample.createCriteria().andFacilityIdEqualTo(facilityId);
        List<CarInfoPO> carInfoPOS = carInfoPOMapper.selectByExample(carInfoPOExample);
        if (carInfoPOS.isEmpty()){
            throw new AppErrorException(AppError.CAR_NOT_FIND_ERROR);
        }
        List<Long> carId = carInfoPOS.stream()
                .map(CarInfoPO::getCarId)
                .toList();
        CarTaskPOExample e = new CarTaskPOExample();
        e.createCriteria().andVehicleIdIn(carId).andEndDateGreaterThanOrEqualTo(DateUtil.removeTime(date));
        return carTaskPOMapper.countByExample(e);
    }

}
